/*-+-*****************************************************************************
 Copyright (C) 2009-2012 Oceanside Software Corporation (R)
 Dallas, Texas

 Author       : Jason T. Brower
 Purpose      : This file is part of a point-of-sale software package
                originally written for Table-Service Restaurants.
              
 Date         : July 8th of 2012
              
 History      : The application that this software file belongs to was 
                written over a 3-Year period.  The first version was written
                in C# .Net 3.5 using Windows Forms.  Being new to .Net at
                the time, I soon learned of Windows Presentation Foundation,
                liked the graphics capabilities and databinding so I
                migrated to WPF.  When the .Net 4.0 framework was released
                the application was migrated from 3.5 to 4.0. Now today,
                .Net 4.5 RC is out and I was already in process of migrating
                before I made this public.
                
Excuse Me     : Please excuse the coding style, it is not representative of
                my typical work.  During the three years I was under a very
                tight budget, constantly running out of funding and was 
                working 18 hour days hyped up on 5-Hour Energy.  The 
                design is not textbook.  It is monolythic because of
                previous issues I will not get into.  There are few comments
                in the code and the ones that are there may be incorrect.
                
What it is not: This is not the exact version that I took through PA-DSS 2.0
                nor is it the exact version running at my customer sites.
                I removed some details for security purposes including some
                encryption algorithms.  The reporting was removed because
                I was including a third party library that cannot be 
                published with this Open Source.
                
What it is    : This application has been running at high volume restaraunts
                for over a year.  It never freezes, crashes or does anything
                unexpected.  So long as it is built, installed and configured
                correctly, it is a strong system that we can all enhance.

Contact       : Please note that I can no longer work for free.  However, you
                can reach me at information@oceansidesw.com.                                                      

*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;


namespace Oceanside
{
    /// <summary>
    /// Interaction logic for MainControl.xaml
    /// </summary>
    public partial class FullKeyboard : ModalWindow
    {
        public static UserResponse LastResponse
        {
            get;
            set;
        }
        private static List<Control> _tabOrderTbList;
        private static int _tabOrderListIndx = 0;

        private static Brush _highlightBrush = new SolidColorBrush(Color.FromRgb(0xFF, 0xFA, 0x2A));
        private static Brush _nonHighlightBrush = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xFF));
        /// <summary>
        /// Constructor.
        /// </summary>
        private FullKeyboard()
        {
            modalDialogIsOpen = false;
            CurrentlyOpenInstance = null;
            this.InitializeComponent();
            keyCapsLock.IsCapLockKey = true;
            _highlightBrush.Freeze();
            _nonHighlightBrush.Freeze();
            this.Owner = PosWindow.MainPosWindow;
        }

        /// <summary>
        /// 
        /// </summary>
        public static void Init()
        {
            activeKeyboard = new FullKeyboard();
        }

        /// <summary>
        /// 
        /// </summary>
        private static FullKeyboard activeKeyboard = null;
        public static FullKeyboard ActiveKeyboard
        {
            get { return FullKeyboard.activeKeyboard; }
            set { FullKeyboard.activeKeyboard = value; }
        }

        private static bool useAutoCapsMode = false;
        public static bool UseAutoCapsMode
        {
            get { return useAutoCapsMode; }
            set { useAutoCapsMode = value; }
        }

        /// <summary>
        /// This list will hold the gui key presses as they come in from the gui keyboard window.
        /// </summary>
        private static String guiKeyPressedString = "";
        public static String GuiKeyPressedString
        {
            get { return FullKeyboard.guiKeyPressedString; }
            set { FullKeyboard.guiKeyPressedString = value; }
        }
        private static object guiKeyPressStringLocker = new object();

        /// <summary>
        /// 
        /// </summary>
        public static object GuiKeyPressStringLocker
        {
            get { return FullKeyboard.guiKeyPressStringLocker; }
            set { FullKeyboard.guiKeyPressStringLocker = value; }
        }


        /// <summary>
        /// 
        /// </summary>
        public static void TabDetected()
        {
            if (_tabOrderTbList != null)
            {
                ///Clear the strings
                ActiveKeyboard.textBoxValue.Text = "";
                guiKeyPressedString = "";

                ///Unhighlight the currently selected tab box.
                _tabOrderTbList[_tabOrderListIndx].Background = _nonHighlightBrush;

                ///Do some bounds checking with array index wrapping.
                if (_tabOrderListIndx < _tabOrderTbList.Count - 1)
                {
                    _tabOrderListIndx++;
                }
                else
                {
                    _tabOrderListIndx = 0;
                }

                if (_tabOrderTbList[_tabOrderListIndx].IsVisible)
                {
                    ///Highlight and focus the newly selected text box.
                    _tabOrderTbList[_tabOrderListIndx].Background = _highlightBrush;
                    _tabOrderTbList[_tabOrderListIndx].Focus();
                }
                else
                {
                    TabDetected();
                }
            }
        }

        /// <summary>
        /// Used to exchange keyboard scan codes for ASCII char strings.
        /// </summary>
        private static ScanCodes codeScanFormatter = new ScanCodes();
        internal static ScanCodes CodeScanFormatter
        {
            get
            {
                return codeScanFormatter;
            }
            set { codeScanFormatter = value; }
        }
        private static object isGuiKeyboardModeLocker = new object();

        /// <summary>
        /// 
        /// </summary>
        public static void LockCaps()
        {
            ActiveKeyboard.keyCapsLock.HighlightBorder();
            KeyboardKey.CapsIsLocked = true;
            codeScanFormatter.ResetCase();
            codeScanFormatter.IsCaps = true;
        }

        static System.Windows.Window _childWindow = null;
        public static System.Windows.Window ChildWindow
        {
            get { return FullKeyboard._childWindow; }
            set { FullKeyboard._childWindow = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public void HideMe(bool isCancel = false)
        {
            ActiveKeyboard.keyCapsLock.ResetBorder();
            KeyboardKey.CapsIsLocked = false;
            codeScanFormatter.ResetCase();

            this.Hide();

            if (_tabOrderTbList != null)
            {
                if (isCancel)
                {
                    int i = 0;
                    foreach (Control c in _tabOrderTbList)
                    {
                        if (c is TextBox)
                        {
                            (c as TextBox).Text = originalStringsList[i++];
                        }
                    }
                }
                ///Unhighlight the currently selected tab box.
                _tabOrderTbList[_tabOrderListIndx].Background = _nonHighlightBrush;
            }

            textBoxValue.Text = "";
            labelMessage.Text = "";

            CurrentlyOpenInstance = null;
            ModalDialogIsOpen = false;
            SetSmallMode(false);

            this.Topmost = false;

#if !_DEBUG
            if (ChildWindow != null)
            {
                ChildWindow.Topmost = true;
            }
            else if (PosWindow.MainPosWindow != null)
            {
                PosWindow.MainPosWindow.Topmost = true;
            }
#endif

            if (isCancel)
            {
                LastResponse = UserResponse.EXIT;
            }
            else
            {
                LastResponse = UserResponse.ENTER;
            }
        }

        List<string> originalStringsList = new List<string>();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tbList"></param>
        public void SetTabOrderList(List<Control> tbList)
        {
            _tabOrderListIndx = 0;
            _tabOrderTbList = tbList;

            useAutoCapsMode = false;
            originalStringsList.Clear();

            ///Start by assuring that all text boxes are not highlighted.
            foreach (Control c in _tabOrderTbList)
            {
                if (c is TextBox)
                {
                    originalStringsList.Add((c as TextBox).Text);
                }
                c.Background = _nonHighlightBrush;
            }

            ///Now highlight and select the first text box.
            _tabOrderTbList[_tabOrderListIndx].Background = _highlightBrush;
            _tabOrderTbList[_tabOrderListIndx].Focus();
        }

        /// <summary>
        /// 
        /// </summary>
        public void ShowMe(List<Control> tbList = null, bool listAlreadySet = false, bool dontAutoCap = false)
        {
            _tabOrderListIndx = 0;

            if (!listAlreadySet)
            {
                _tabOrderTbList = tbList;

                if (_tabOrderTbList != null)
                {
                    useAutoCapsMode = false;
                    originalStringsList.Clear();

                    ///Start by assuring that all text boxes are not highlighted.
                    foreach (Control c in _tabOrderTbList)
                    {
                        if (c is TextBox)
                        {
                            originalStringsList.Add((c as TextBox).Text);
                        }
                        c.Background = _nonHighlightBrush;
                    }

                    ///Now highlight and select the first text box.
                    _tabOrderTbList[_tabOrderListIndx].Background = _highlightBrush;
                    _tabOrderTbList[_tabOrderListIndx].Focus();
                }
                else
                {
                    if (dontAutoCap)
                    {
                        useAutoCapsMode = false;
                    }
                    else
                    {
                        useAutoCapsMode = true;
                    }
                }
            }
            guiKeyPressedString = "";

            CurrentlyOpenInstance = this;
            ModalDialogIsOpen = true;
            this.Topmost = true;
            PosWindow.MainPosWindow.Topmost = false;
            this.ShowDialog();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="isSmall"></param>
        public void SetSmallMode(bool isSmall = true)
        {
            if (isSmall)
            {
                borderQuestion.Visibility = System.Windows.Visibility.Hidden;
            }
            else
            {
                borderQuestion.Visibility = System.Windows.Visibility.Visible;
            }
        }

        /// <summary>
        /// Holds the value of the entered text.
        /// </summary>
        public String TextBoxValue
        {
            get { return textBoxValue.Text; }
            set
            {
                textBoxValue.Text = value;

                if (_tabOrderTbList != null)
                {
                    if (_tabOrderListIndx < _tabOrderTbList.Count)
                    {
                        Control c = _tabOrderTbList[_tabOrderListIndx];
                        if (c is TextBox)
                        {
                            ((TextBox)c).Text = value;
                        }
                        else if (c is PasswordBox)
                        {
                            ((PasswordBox)c).Password = value;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public void SetMessage(String message)
        {
            labelMessage.Text = message;
        }
    }
}
